package isquirrel.recommender;

import isquirrel.DBpediaCollection;
import isquirrel.DBpediaWorker;
import isquirrel.beans.Interest;
import isquirrel.beans.Recommendation;
import isquirrel.beans.Url;
import isquirrel.beans.User;
import isquirrel.semantic.DBpedia;
import isquirrel.util.HibernateUtil;
import isquirrel.util.URL;

import java.io.UnsupportedEncodingException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class StaticRecommender extends Recommender {

	public static void insertRecommendations(User user, Interest interest) {
//		System.out.println("Adding Recommendations ..");
		DBpedia dbPedia = new DBpedia();
		DBpediaCollection dbPediaCollection = new DBpediaCollection();
		
		List<String> subjects = dbPedia.getMoreSpecificSubjectsList(interest.getSubjects());
			
		subjects.addAll(interest.getSubjects());		
		int size = subjects.size();
		int iterations_needed = (int) Math.ceil((double) size / 4); //get urls for 3 subjects at a time  

		int start = 0;
		int finish = 0;
		for (int i = 0; i<iterations_needed; ++i) {
			finish+=4;
			finish = (finish >= size) ? size : finish;
			// worker gets urls for one subject - stores them in dbpediaCollection.urls
			Thread dbpediaWorker = new Thread(new DBpediaWorker(subjects.subList(start, finish), dbPediaCollection, dbPedia)); 
			dbpediaWorker.start();
			start = finish;
			dbPediaCollection.incrementWorkers();
		}
		while (!dbPediaCollection.workersDone()) {
			try {
				Thread.sleep(100); //threads haven't finished yet - release processor 
			}catch(InterruptedException ie) {
				ie.printStackTrace();
			}
		}
		//threads have finished accumulating urls 
		Set<String> urls = dbPediaCollection.urls();
			
		HibernateUtil.getSession().refresh(user);
		for (String url : urls) {
			Url u = new Url(URL.getTitle(url), url, "static");
			user.addUrl(u);
		}
//		System.out.println("done. recommendations added.");

		HibernateUtil.getSession().saveOrUpdate(user);
	}

	public static void deleteRecommendations(User user, Interest interest) {
		if (user.getInterests().remove(interest)) {
			updateRecommendations(user);
		}
	}

	/**
	 * Refresh the list of static recommendations with the up-to-date interests
	 * list.
	 * 
	 * This function will get the list of all the static recommendations with
	 * the current interests and will update the list of static recommendations
	 * (add new/remove recommendations).
	 */
	public static void updateRecommendations(User user) {
//		System.out.println("Updating Static Recommendations");
		DBpedia dbPedia = new DBpedia();

//		System.out.println("Getting more specific subjects..");
		// Create a list of subjects for all the available interests
		// This list will be used later on to bring all the url recommendations
		// at once.
		Set<String> subjects = new HashSet<String>();
		for (Interest i : user.getInterests()) {
			subjects.addAll(dbPedia.getMoreSpecificSubjects(i.getSubjects()));
			subjects.addAll(i.getSubjects());
		}

//		System.out.println("Getting url recommendations from subjects..");
		Set<String> newUrls = dbPedia.getUrlsFromSubjects(subjects);

		updateUrls(user, newUrls, "static");
	}

	public static List<Recommendation> getRecommendations(User user,
			boolean liked, int howMany, boolean getAbstract) throws UnsupportedEncodingException {
		return getRecommendations(user, liked, howMany, "static", getAbstract);
	}

	
}
